駭客?聽起來真的超酷


Posted by 小小碼農 on 2021-06-22

這篇會說明基本常見的駭客入侵與防禦的方法

  • 有沒有印象使用瀏覽器的時候,莫名其妙被導到不知名網站,接著原本網站就莫名的被登出....?
  • 或是忘記帳密時,收到一封有你帳密的 email,跟你說這是你忘記的帳密...?

諸如此類狀況,當下可能覺得還好,沒事,但事後回想,心裡還是會有點毛毛的....好像有種怪怪的感覺正在萌芽....

請說明雜湊跟加密的差別在哪裡,為什麼密碼要雜湊過後才存入資料庫

得先說明密碼為何不能存明碼。

雖然後端資料庫在儲存使用者的密碼時,不能存明碼已經是一種常識,儘管大家都覺得自家資料庫很安全,絕不可能攻破,但攻擊簡單防守難,攻擊者只要找到一個漏洞就可以鑽,防守者卻得思考所有可能的攻擊,防守範圍根本不一樣。

這時候就要預設最壞情況 -- 資料庫被駭了,駭客得到密碼了,不過好在不是存明碼的形式,駭客可能可以破解,但或許要花上十年、二十年,應該沒有多少駭客會願意,這樣我們或許就可以說我們防守成功。

接下來是一些超前部署部分,看看如何做到即使資料庫被駭了,使用者的真實密碼也不會洩漏出去

  • 雜湊 (Hash)
    不可逆。就算知道了雜湊過後的秘文,也無法回推出明文

hash

  • 將明文丟進公式後變成一串秘文
  • 無論明文內容長短,透過雜湊演算法出來都是一樣的長度
  • 同樣的輸入經過雜湊,保證一定會得到同樣的輸出
  • 多對一關係,不同內容可能對應到同一組值,此情況稱為「碰撞(collision)」,但機率極低

    補充:一個雜湊函式的好壞也取決於是否容易發生碰撞

  • 由於無法逆向解出明文,安全性相較加密來的高

  • 常見演算法:SHA 系列

    方法:

  1. password_hash()
    $password = password_hash($_POST['password'], PASSWORD_DEFAULT);
  • 為 PHP 內建的 hash() 函式,只需要將加密方式傳給 hash() 函式。可以直接指明 sha256, sha512, md5, sha1 等加密方式
    ex: $password = hash("sha256", $password);

  • 將經過演算法的密碼儲存在變數中

  • 第一個參數是原始 password,第二個參數是演算法,建議可使用 PASSWORD_DEFAULT,每次處理都會產生隨機的 SALT
  1. password_verify()

    $password = 'ilovecoding12345' // 原始密碼
    
    if(password_verify($password, $row_['password])) {
     $_SESSION['name'] = $username;
    } else {
     header('Location: login.php?errCode=2');
     die();
    }
    
    header('Location: index.php');
    
  • 檢查輸入的密碼是否存在相對應的資料,是則導回首頁,否則導回登入頁並報錯
  • 將經過 password_hash() 處理的密碼,進行驗證,用於登入功能
  • password_verify('使用者輸入的密碼', '資料庫裡的密碼'),根據回傳的 boolean 值,進行操作
  • 加密 (Encryption)
    可逆。知道了加密後的秘文,只要知道金鑰,就可以還原出明文

    • 將明文資訊改變成難以讀取的密文,例如常見的「凱薩加密」,可透過「解密」還原內容
    • 加密與解密都同樣要透過金鑰來執行
    • 一對一對應關係
    • 分為對稱與非對稱式

      • 對稱式加密:

        • AES, DES 等
        • 發送者與持有者持有相同金鑰來加解密資訊
        • 傳遞金鑰的過程中(發送 request, response)被竊取資訊的話,再強的加密演算法都沒有用,因此有了非對稱式加密
        • 明文 ABC,經由加密後每位向後移三位,變成 CDE,這樣就是簡單的對稱式加密
      • 非對稱式:

        • RSA, DSA 等
        • 使用者都擁有一對金鑰,公鑰加密,私鑰解密
        • 訊息由其中一把公鑰加密,必須由另一把私鑰解密
        • 安全性相較對稱式來得更高
        • 有五人 ABCD 與 E,還有一口箱子,E 將唯一一把私鑰留給自己,公鑰分別發給其餘四人一人一把,並且說:「有人想跟他說悄悄話就把訊息放到箱子裡上鎖」,過幾天 E 打開箱子真的有訊息。

        藉由上述,我們知道只有 E 能開箱子,因為只有他有唯一一把私鑰,同時確保只有 E 能看到其中的內容

額外補充 -- 雜湊加鹽(SALT)

一樣的密碼經過雜湊以後,就一定會有一樣的雜湊值,針對這一點,建立一個常用字串對照雜湊值的表格,藉此強硬破解雜湊後的密碼

我們叫它「彩虹表」

至於如何防範?我們只要給密碼加鹽(SALT)就可以。
在原本密碼雜湊前,先加入一段固定字串(SALT),比如在原本密碼前我們都先加上 1234

ilovecoding1234(SALT) -> 1234ilovecoding1234

這樣即使有了對照表,也不知道加入了什麼鹽或是怎麼加的,短時間也難以破解。
本人輸入密碼的話,只要照著原本方式加鹽回去,做雜湊,比較是否吻合資料庫中的雜湊值就可以了。

雜湊常用在平台上的密碼驗證,因為平台實際上不需要知道使用者真正輸入的密碼,透過雜湊不可逆的機制,可以最好的保護使用者的明碼。而區塊鏈則會用到不對稱式加密的機制,讓一個訊息能透過私鑰及公鑰被加密傳輸與保護。而編碼基本上毫無安全性可言,換個方式表達而已,像是摩斯密碼,只要有人懂這套規則就能輕易轉譯回來。

簡單說,密碼存明碼就是違反資訊安全的起手式!!不可姑息!!

includerequireinclude_oncerequire_once 的差別

此四種函式的作用都是包含並執行指定檔案,最主要差別在使用時機

  • include()和 require()差別

    • include() 引入檔案時,如遇到錯誤,會提示錯誤並繼續執行。
    • require() 引入檔案時,如遇到錯誤,會提示錯誤並終止執行。
    • require() 通常放在 php 頁面最前,php 在執行前就會先讀入 require()引入的檔案,檔案內容會變成此頁指令碼的一部份,include()只在用到時才放進來,通常是放在流程控制的處理區段中,php 指令碼在執行到它時,才會將檔案包含進來。即 require()是預載入機制,位置在指令碼最前面,一開始就引入所有可能用到的檔案;include()是即用即載入,位置靈活。
  • 在後面加上 _once 的區別

    • include()、require()執行即包含檔案,不會對引入的檔案進行比較判斷,可能會出現重複包含的情況;而 include_once()、require_once()在包含時會先判斷檔案是否已經包含過了,如果已包含,則不再包含檔案,這樣的引入檔案方式即可以節省資源,又可避免重複定義的錯誤。

請說明 SQL Injection 的攻擊原理以及防範方法

SQL injection

  • SQL 語法常用於 database 系統中,攻擊者可透過更改語法邏輯或加入惡意特殊指令方式,竊取或修改資料

  • 防禦方法:prepared statement
    「參數化查詢」或是「預處理」,簡單說就是另外準備好參數來給值,在所有需要填入數值或資料的地方。

    Prepared Statement 會替 SQL 語句進行預處理,利用提供的 bindValue 或 bindParam 函式將欲查詢的參數或數值綁定上去,底層查詢時,其參數會保證作為數值傳遞,不會成為 SQL 語句的一部份,因此可避免掉 SQL Injection 的問題

  • 方法舉例

      <?ph
        $sql = 'INSERT INTO comments (username, content) VALUE (?, ?)'; // 準備好 SQL 語法,用問號(稱為佔位符或參數)替換查詢中的所有變量
        $stmt = $connect->prepare($sql); // 準備結果查詢
        $stmt->bind_param('ss', $username, $content); //將所有變量綁定到先前準備的語句
        $result = $stmt->execute(); // 執行語句
      ?>
    

    建議所有要下 sql 的地方都要加上預處理方法(prepared statement)

請說明 XSS 的攻擊原理以及防範方法

XSS
Cross-site scripting,跨網站指令碼攻擊。

  • 透過網頁開發時的漏洞,在使用者可以輸入訊息的地方,輸入惡意指令碼,透過被攻擊者的身份去執行一些管理的動作以得到想要的資訊(帳號、密碼等),或是導向到釣魚網站。

惡意指令碼通常是 JavaScript,但其他語言 HTML, CSS, JAVA 等也都有可能

  • 防禦方法
    htmlspecialchars()

    將預定義的特殊字元轉換成 HTML 僅能顯示用的編碼

    • 語法
      htmlspecialchars( $string , $quote_flags , $encoding , $double_encode )

      • $string: 須轉換的字串
      • $quote_flags: 用來設定引號的轉換,基本上建議使用 ENT_QUOTES 單雙引號都轉換(預設是僅轉換雙引號)
      • $encoding: 用來設定要轉換的編碼,預設是 UTF-8
      • $double_encode: 是否要對全部進行轉換,預設值是轉換全部的 HTML 碼

請說明 CSRF 的攻擊原理以及防範方法

Cross Site Request Forgery,跨站請求偽造

  • 當用戶登錄網站時,聯覽器會記錄 cookies,如果用戶未登出或 cookies 未過期(關閉瀏覽器並不代表網站已登出或 cookies 可立即過期)的期間,造訪了其他危險或不知名網站,點擊了攻擊者的連結,便會向原網站發出某項功能請求(request),原網站的伺服器接收後會誤以為是用戶合法操作而執行。

簡單舉例,可能是在某大型平台點擊了某項連結,進而被導到其他(釣魚)網站,點了不知名的按鈕,然後就被駭客利用你本人發送 request 去取得某平台的資料或做出某項行為。

  • 防範手法

    • 用戶端

      • 使用完記得登出,也別隨意瀏覽不明網站
      • 避免在瀏覽器自動儲存帳密
      • 基本上,用戶端能做的不多
    • 伺服器端

      • request 裡面有一個欄位叫做 referer,代表這個 request 從哪裡來,可以檢查這個欄位是不是合法 domain
      • 加上圖形或簡訊驗證碼,常見於銀行帳戶等需要高度安全的領域,若每個網頁都這樣,也實在不方便
      • 加上 CSRF token,在 form 裡面加上一個 hidden 欄位,叫做 CSRF token,其中填入由 server 隨機產生的一組亂碼並且存在 server 的 session 中,提交後,server 比對 form 中的 token 是否跟 session 中的一樣,來確認是不是本人發出的 request,每一段不同 session 就應該要更換一次 CSRF token,但是攻擊者若是掌握任一個你底下的 subdomain,就可以幫你寫 cookie 且順利攻擊
      • Double Submit Cookie,解法與第 CSRF token 類似,前半段同樣都由 server 產生一組隨機的 token 且加在 form 上面,不同點在後面,不用把這個值寫在 session 保存在 server 外,同時讓 client side 設定一個叫 CSRF token 的 cookie,值也是一組 cookie,利用cookie 只會從相同 domain 帶上來的機制,使攻擊者無法從不同 domain 得到此 cookie
    • 瀏覽器端

      • SameSite cookie,簡單說只要 cookie 不是從原網頁來的就會被消除掉,但目前只有 chrome 支持

      • 原先:Set-Cookie: session_id=ewfewjf23o1;

      • 修正:Set-Cookie: session_id=ewfewjf23o1; SameSite

上述有幾點攻擊手法都是類似的,總歸一句:

「 永遠不要相信來自 client 的資訊 」

就可以避免掉很多惡意攻擊


#hacker







Related Posts

如何在 Windows 安裝 OpenPose 跟使用 Python API 來偵測人體姿態

如何在 Windows 安裝 OpenPose 跟使用 Python API 來偵測人體姿態

Go json and embedded struct

Go json and embedded struct

Day 91

Day 91


Comments